<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

</body>

</html>

<script>
    /*
    let obj1 = {
        name: '张三',
        age: 18,
        like: [1,[1,2]]
    }

    // let obj2 = obj1
    // let obj2 = shallowCopy(obj1)
    // function shallowCopy (obj) {
    //     let newObj = {}
    //     if (typeof obj !== 'object') {
    //         return
    //     }
    //     for (let key in obj) {
    //         newObj[key] = obj[key]
    //     }
    //     return newObj
    // }
    // let obj2 = Object.assign({},obj1)

    function deepCopy (obj) {
        let objClone = Array.isArray(obj)?[]:{};
        if(obj && typeof obj==="object"){
            for(key in obj){
                if(obj.hasOwnProperty(key)){
                    //判断ojb子元素是否为对象，如果是，递归复制
                    if(obj[key]&&typeof obj[key] ==="object"){
                        objClone[key] = deepCopy(obj[key]);
                    }else{
                        //如果不是，简单复制
                        objClone[key] = obj[key];
                    }
                }
            }
        }
        return objClone
    }

    let obj2 = deepCopy(obj1)









    obj2.name = '李四',
    obj2.like[1] = [3,4]

    console.log('obj1',obj1)
    console.log('obj2',obj2)

    const a1 = [1,2,3]
    const a2 = [4,5,6]
    // let a = new Set(['a','b','c']);
    // a.forEach((v,k) => console.log(k + ' : ' + v));

    let a = new Map([
        ['name','leo'],
        ['age',18]
    ])

    for (let i of a.keys()){
        console.log(i)
    };
    for (let i of a.values()){
        console.log(i)
    };
    for (let i of a.entries()){
        console.log(i)
    };
    a.forEach((v,k,m)=>{
        console.log(`key:${k},value:${v},map:${m}`)
    })
*/
    /*
    function sum (x) {
        console.log(arguments)
        if (arguments.length == 2) {
            return arguments[0] + arguments[1];
        }

        return function(y) {
            return x + y;
        }
    }
    console.log(sum(2,3))
    */

    /*
        let arr = [1,2,3,4,5,6,7,8,9]
        console.log([...arr.filter((item) => {return item & 1}), ...arr.filter((item) => {return item % 2 === 0})])
        */

    /*
    var cars = ['BMW','Benz', 'Benz', 'Tesla', 'BMW', 'Toyota'];
    var carsObj = cars.reduce(function (obj, name) {
        console.log(obj)
    obj[name] = obj[name] ? ++obj[name] : 1;
    return obj;
    }, {});
    console.log(carsObj); // => { BMW: 2, Benz: 2, Tesla: 1, Toyota: 1 }
    */

    /*
    const flatten = (arr, depth = 1) =>
    depth != 1
        ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v, depth - 1) : v), [])
        : arr.reduce((a, v) => a.concat(v), []);
    console.log(flatten([1, [2], 3, 4]));                             // [1, 2, 3, 4]
    console.log(flatten([1, [2, [3, [4, 5], 6], 7], 8], 2));           // [1, 2, 3, [4, 5], 6, 7, 8]
    */

    /*
        function fun(n, o) {
            console.log(o)
            return {
                fun: function (m) {
                    return fun(m, n)
                }
            }
        }

        var a = fun(0)
        console.log(a.fun(1).fun(2))
        // a.fun(1)
        // a.fun(2)
        // a.fun(3)

        // var b = fun(0).fun(1).fun(2).fun(3)

        // var c = fun(0).fun(1)
        // c.fun(2)
        // c.fun(3)
    */
    /*   async function async1() {
           console.log( 'async1 start' );
           await async2();
           console.log( 'async1 end' );
       }
       async function async2() {
           console.log( 'async2' );
       }
       async1();
       console.log( 'script start' );
       */
    // console.log(document.addEventListener)
    // if (document.attachEvent) {
    //     console.log(1)
    // } else {
    //     console.log(0)
    // }

/*
    function deepCopy(obj, cache = []) {
        // just return if obj is immutable value
        if (obj === null || typeof obj !== 'object') {
            return obj
        }

        // if obj is hit, it is in circular structure
        const hit = find(cache, c => c.original === obj)
        // console.log(hit);
        if (hit) {
            return hit.copy
        }

        const copy = Array.isArray(obj) ? [] : {}
        // put the copy into cache at first
        // because we want to refer it in recursive deepCopy
        cache.push({
            original: obj,
            copy
        })
        console.log(Object.keys(obj));

        Object.keys(obj).forEach(key => {
            copy[key] = deepCopy(obj[key], cache)
            // console.log(copy[key]);
        })

        return copy
    }

    let obj = {
        name: '嘻嘻嘻',
        age: 18,
        arr: [1,2,[3,4]]
    }
    deepCopy(obj)
    // console.log(deepCopy(obj))
*/

/*
    let arr = [1,2,2,3,1,1,4,4,4,5,3,3,6,2,2,2,2,3,1]
    let newArr = []
    arr.forEach((ele,ind) => {
        if (arr[ind - 1] === arr[ind]) {

        } else {
            newArr.push(ele)
        }
    })
    console.log(newArr)
*/
/*
    value = '1234'
    console.log(value[1])
*/
/*
    let obj = {
        name: [1,2,3,4],
        age: [12,13,14]
    }
    console.log(!obj[name])
*/
/*    function find (list, f) {
        // console.log(f)
        return list.filter(f)[0]
    }

    function deepCopy (obj, cache = []) {
        if (obj === null || typeof obj !== 'object') {
            return obj
        }

        const hit = find(cache, c => c.original === obj)
        if (hit) {
            return hit.copy
        }

        const copy = Array.isArray(obj) ? [] : {}
        cache.push({
            original: obj,
            copy
        })

        Object.keys(obj).forEach(key => {
            copy[key] = deepCopy(obj[key], cache)
        })

        return copy
    }

    let obj = {
        name: '嘻嘻嘻',
        age: 18,
        arr: [1,2,[3,4]]
    }

    console.log(deepCopy(obj))
*/
    //原生实现map
/*    Array.prototype.symap = function(fn) {
        let _this = this
        let newArr = []
        if (typeof fn !== 'function') {
            throw new TypeError(`${fn} is not a function`)
        }
        if (_this.length === 0) return []
        _this.forEach((ele, index, arr) => {
            newArr.push(fn(ele, index, arr))
        })
        return newArr
    }
    // reduce 实现 map
    Array.prototype.smap = function (fn) {
        const _this = this
        if (typeof fn !== 'function') {
            throw new TypeError(`${fn} is not a function`)
        }
        if (_this.length === 0) return []
        return _this.reduce((acc, cur, index, arr) => {
            acc.push(fn(cur, index, arr))
            return acc
        }, [])
    }
    // reduce 实现 filter
    Array.prototype.sfilter = function (fn) {
        const _this = this
        if (typeof fn !== 'function') {
            throw new TypeError(`${fn} is not a function`)
        }
        if (_this.length === 0) return []
        return _this.reduce((acc, cur, index, arr) => {
            if (fn(cur, index, arr)) {
                acc.push(cur)
            }
            return acc
        }, [])
    }
    let arr = [1,2,3,4,5,6,5,4,3,2,1]
    let arr1 = []
    console.log(arr.symap(item => item * 2))
    // console.log(arr.smap(item => item * 2))
    // console.log(arr.sfilter(item => item > 2))
*/

  /*  // 实现promise finally
    Promise.prototype.sFinally = function(cb){
        const p = this.constructor
        return p.then(
            value  => P.resolve(callback()).then(() => value),
            reason => P.resolve(callback()).then(() => { throw reason })
        )
    }
    */
    // function s4 () {
    //     return Math.floor((1 + Math.random()) * 0x10000)
    //         .toString(16)
    //         .substring(1)
    // }
    // console.log(s4() + s4() + '-' + s4() + '-' + s4() + '-' +
    // s4() + '-' + s4() + s4() + s4())

    // var nums1 = [1,2,2]
    // var nums2 = [1,2,1,2,3]
    // const p = function(arr1, arr2){
    //     if(arr1.length > arr2.length) {
    //         return arr2.filter(ele => {
    //             return arr1.includes(ele)
    //         })
    //     } else {
    //         return arr1.filter(ele => {
    //             return arr2.includes(ele)
    //         })
    //     }
    // }
    // console.log(p(nums2, nums1))

    // let a = new Set([1, 1, 2, 3]);
    // let b = new Set([4, 1, 3, 2]);
    // // 并集
    // let union = new Set([...a, ...b]);
    // // Set {1, 2, 3, 4}


    // // 交集
    // let intersect = new Set([...a].filter(x => b.has(x)));
    // // set {2, 3}

    // // 差集
    // let difference = new Set([...a].filter(x => !b.has(x)));
    // // Set {1}
    // console.log(intersect)

    // class lazyManClass {
    //     constructor (name) {
    //         this.name = name
    //         this.task = []
    //         console.log(`我叫${name}`)
    //         setTimeout(() => {
    //             this.next()
    //         })
    //     }
    //     sleep (time) {
    //         this.time = time
    //         const fn = () => {
    //             setTimeout(() => {
    //                 console.log(`等待了${this.time}秒`)
    //                 this.next()
    //             }, this.time * 1000)
    //         }
    //         this.task.push(fn)
    //         return this
    //     }
    //     sleepFirst (time) {
    //         this.time1 = time
    //         const fn = () => {
    //             setTimeout(() => {
    //                 console.log(`等待了${this.time1}秒`)
    //                 this.next()
    //             }, this.time1 * 1000)
    //         }
    //         this.task.push(fn)
    //         return this
    //     }
    //     eat(food) {
    //         const fn = () => {
    //             console.log(`I am eating ${food}`)
    //             this.next()
    //         }
    //         this.task.push(fn)
    //         return this
    //     }
    //     next () {
    //         const fn = this.task.shift()
    //         fn && fn()
    //     }
    // }

    // function lazyMan (name) {
    //     return new lazyManClass(name)
    // }

    // lazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(4).eat('junk food')



    // 最长字符串的长度
    // var lengthOfLongestSubstring = function(s) {
    //     var res = 0; // 用于存放当前最长无重复子串的长度
    //     var str = ""; // 用于存放无重复子串
    //     var len = s.length;
    //     for(var i = 0; i < len; i++) {
    //     var char = s.charAt(i);
    //     var index = str.indexOf(char);
    //     console.log(char)
    //     console.log('index：', index)
    //     if(index === -1) {
    //         str += char;
    //         res = res < str.length ? str.length : res;
    //     } else {
    //         str = str.substr(index + 1) + char;
    //     }
    //     console.log('str:', str)
    //     }
    //     return res;
    // };

    // lengthOfLongestSubstring("abcabcbb")

//     var findMedianSortedArrays = function(nums1, nums2) {
//         let arr = [...nums1, ...nums2]
//         console.log(arr)
//         if (arr.length == 1) {
//             return arr[0]
//         }
//         if (arr.length % 2 !== 0) {
//             return arr[(arr.length-1) / 2].toFixed(1)
//         } else {
//             return ((arr[arr.length / 2 - 1] + arr[arr.length / 2 + 1]) / 2).toFixed(1)
//         }
//     };
// console.log(findMedianSortedArrays([], [1,2,3,4,5]))


    // 返回只出现一次且在首位的字符串
// function maxStr (str) {
//     let obj = {}
//     let result = []
//     for (let i = 0; i < str.length; i ++) {
//         const index = result.findIndex(e => { return e === str[i]})
//         if (!obj[str[i]]) {
//             obj[str[i]] = 1
//             result.push(str[i])
//         } else {
//             if (index !== -1) {
//                 result.splice(index, 1)
//             }
//         }
//     }
//     return result[0]
// }

// function maxStr (str) {
//     const Str = str.split('')
//     let result = []
//     const obj = Str.reduce((preValue, curValue) => {
//         if (!preValue[curValue]) {
//             preValue[curValue] = 1
//         } else {
//             preValue[curValue] ++
//         }
//         return preValue
//     }, {})
//     Object.keys(obj).forEach(e => {
//         if (obj[e] === 1) {
//             result.push(e)
//         }
//     })
//     return result[0]
// }

// console.log('maxStr:', maxStr('absscacaedrdbbdfssx'))

    // 冒泡排序
    /**
     * 相邻元素进行相互比较，判断大小交换位置，循环数组长度
     * */
    // function bubbleSort (arr) {
    //     arr.forEach((a, i) => {
    //         arr.forEach((b, j) => {
    //             if (b > arr[j+1]) {
    //                 let temp = arr[j+1]
    //                 arr[j+1] = b
    //                 arr[j] = temp
    //                 console.log('arr:', arr)
    //             }
    //         })
    //     })
    //     return arr
    // }
    //
    // console.log('bubbleSort:', bubbleSort([4, 3, 2, 2, 6, 7, 3, 1]))

//    选择排序
    /**
     * 用每一个元素与所有元素相比较，找出最小的元素索引保存，赋值，外层循环长度减一，内层不变。
     * @type {number[]}
     */
    // const arr = [4, 3, 2, 2, 6, 7, 3, 1]
    // function selectSort (arr) {
    //     let minIndex
    //     for (let i = 0; i < arr.length-1; i++) {
    //         minIndex = i
    //         for (let j = i + 1; j < arr.length; j++) {
    //             if (arr[j] < arr[minIndex]) {
    //                 console.log('j:', j)
    //                 minIndex = j
    //             }
    //         }
    //         let temp = arr[i]
    //         arr[i] = arr[minIndex]
    //         arr[minIndex] = temp
    //     }
    // }
    // selectSort(arr)
//    快速排序
//     const arr = [4, 3, 2, 2, 6, 7, 3, 1]
//     function quickSort (arr) {
//         if (arr.length<=1) {
//             return arr
//         }
//         let mid = Math.floor(arr.length/2)
//         let leftArr = []
//         let rightArr = []
//         let num = arr.splice(mid, 1)
//         arr.forEach((q, i) => {
//             if (arr[i] < num) {
//                 leftArr.push(arr[i])
//             } else {
//                 rightArr.push(arr[i])
//             }
//         })
//         return [ ...quickSort(leftArr), ...num, ...quickSort(rightArr)]
//     }
//     console.log('quickSort(arr):', quickSort(arr))
//    希尔排序
//    插入排序
//    归并排序
</script>
